package pprg.main;

import java.util.Arrays;

import pprg.mergesort.MergeSort;
import pprg.mergesort.MergeSortSequential;
import pprg.quicksort.QuickSort;
import pprg.quicksort.QuickSortSequential;
import pprg.util.Util;

public class Main {

	private static int arraySize = 50000000;

	/**
	 * Threshold für parallele Berechnung.
	 * arraySize / n: n sollte 2^k sein, für parallele Berechnung bis
	 * (inklusive) Rekursionslevel k.
	 * 
	 * ausgansarray = rekursionslevel 0
	 * 1x aufteilen = rekursionslevel 1
	 * usw.
	 */
	private static int threshold = arraySize / 4;
	
	public static void main(String[] args) {

		int[] a = Util.randomNumbers(arraySize);
		int[] b = Arrays.copyOf(a, a.length);
		int[] c = Arrays.copyOf(a, a.length);
		int[] d = Arrays.copyOf(a, a.length);

		
		long startParallelMergeSort = System.currentTimeMillis();
		MergeSort.parallelMergeSort(a, threshold);
		long endParallelMergeSort = System.currentTimeMillis();

		long startParallelQuickSort = System.currentTimeMillis();
		QuickSort.parallelQuicksort(b, threshold);
		long endParallelQuickSort = System.currentTimeMillis();

		long startSeqMergeSort = System.currentTimeMillis();
		MergeSort.sequentialMergeSort(c);
		long endSeqMergeSort = System.currentTimeMillis();

		long startSeqQuickSort = System.currentTimeMillis();
		QuickSort.sequentialQuicksort(d);
		long endSeqQuickSort = System.currentTimeMillis();

		if (Util.isSorted(c)) {
			System.out.println("Time for Seq MergeSort: "
					+ (endSeqMergeSort - startSeqMergeSort) + " ms");
		}

		if (Util.isSorted(a)) {
			System.out.println("Time for Parallel MergeSort: "
					+ (endParallelMergeSort - startParallelMergeSort)
					+ " ms Number of Threads: "
					+ MergeSort.getNumberOfThreads());
		}

		if (Util.isSorted(d)) {
			System.out.println("Time for Seq QuickSort: "
					+ (endSeqQuickSort - startSeqQuickSort) + " ms");
		}

		if (Util.isSorted(b)) {
			System.out
					.println("Time for Parallel QuickSort: "
							+ (endParallelQuickSort - startParallelQuickSort)
							+ " ms Number of Threads "
							+ QuickSort.getNumberOfThreads());
		}

		// alternative Sequential versions (object orientated implementation)
		// not used for run time analysis

		// MergeSort Sequential
		// ///////////////////////////////////////////
		int[] tempRandomArray1 = a.clone();
		long start = System.currentTimeMillis();

		MergeSortSequential mss = new MergeSortSequential();
		mss.sorting(tempRandomArray1);

		long stop = System.currentTimeMillis();
		long duration = stop - start;
		if (Util.isSorted(mss.getValues())) {
			System.out
					.println("Object Orientated Mergesort Time - sequential: "
							+ duration + " ms");
		}

		// /////////////////////////////////////////////////////////////////////

		// QuickSort Sequential
		// ///////////////////////////////////////////
		int[] tempRandomArray3 = a.clone();
		start = System.currentTimeMillis();

		QuickSortSequential qss = new QuickSortSequential();
		qss.sorting(tempRandomArray3);

		stop = System.currentTimeMillis();
		duration = stop - start;

		if (Util.isSorted(qss.getValues())) {
			System.out
					.println("Object Orientated Quicksort Time - sequential: "
							+ duration + " ms");
		}
	}
}
